import { Component, OnInit, ViewChild } from '@angular/core';
import { NzFormatEmitEvent, NzTreeNode, NzFormatBeforeDropEvent, NzTreeComponent, NzMessageService } from 'ng-zorro-antd';
import { of, Observable, from } from 'rxjs';
import { Utils, Lang, Status } from '../../../common/helper/util-helper';
import { DepartmentService } from '../../../services/organization/department/department.service';
import { TreeEditComponent } from '../../../components/tree-edit/tree-edit.component';
import { NzModalService } from 'ng-zorro-antd';
import { async } from '@angular/core/testing';


@Component({
  selector: 'app-department-management',
  templateUrl: './department-management.component.html',
  styleUrls: ['./department-management.component.scss']
})
export class DepartmentManagementComponent implements OnInit {
  @ViewChild('treeCom', { static: false }) treeCom: NzTreeComponent;
  @ViewChild('treeEdit', { static: false }) public treeEdit: TreeEditComponent;
  public status = {


    // 原始数据
    initTreeNodes: null,
    // 节点树数据缓存
    treeNodeAll: null,
    // 树数据
    treeNodes: [],
    // 职能描述
    title: null,
    // 部门描述
    description: null,
    // 初始化Params
    aboutParams: {
      // 每页记录数
      maxResultCount: 1000,
      // 当前页码
      skipCount: 0,
      // 部门id
      id: null,
      // 排序
      sort: 1,
      // 层级
      level: 1,
    },
    // 当前选中节点
    activedNode: null,
    // 待编辑节点
    editNode: null,
    // 修改结构模态框状态
    ischangeSort: false,
    // 新增部门模态框状态
    ismodify: false,
    // 关键词搜索
    filter: '',
    // 编辑部门模态框状态
    isedit: false,
    // 删除部门模态框
    isDelete: false,
    // 结构修改成功状态
    isOkLoading: false,
    // 需刷新结构树方法
    refreshTreeNodeFn: null,
    // 当前拖动节点的title
    dragNodeTitle: "",
    // 当前拖动节点的ID
    dragNodeId: null,
    // 当前拖动节点的level
    dragNodelevel: null,
    // 当前拖动节点的parentid
    dragNodePid: null,
    // 当前节点拖动后的前一个id
    dragBeforeNodeid: null,
    // 当前拖动节点的sort
    dragNodeSort: null,
    // 排序数组
    dragArr: [],
    // 当前页面所需要的权限
    pagePermissions: [
      // 'APJ.System.Organizations'
    ],
    // 当前页面权限
    pageAuthorty: { Organizations: null }
  };

  /**
     * 初始化数据
     */
  async init() {

    // 获取部门原始数据
    const parmas = {
      MaxResultCount: this.status.aboutParams.maxResultCount,
      skipCount: this.status.aboutParams.skipCount,
      // 关键词搜索
      filter: this.status.filter,
    };
    await this.departmentService.GetOrganizationUnits(parmas).then((res) => {
      if (res.success) {
        // 保存原始数据
        this.status.initTreeNodes = res.result.items;
      //   this.status.initTreeNodes = res.result.items.sort((a, b) => {
      //     return a.sort - b.sort;
      //   })
      //  console.log(res.result.items.sort((a, b) => {
      //   return b.sort - a.sort;
      // }))
    this.fromOriginToNodeTree(() => {
      // this.message.success('数据加载成功');
    });
  } else {
  this.message.warning(res.error.message);
}
    });

  }


  /*********************************************
     * 从原始数据转换为节点树数据
     * @param originData <any> 原始数据
     * @param callBack <Function> 回调函数
     ******************************************/
  public fromOriginToNodeTree(originData ?: any, callBack ?: Function) {
  if (typeof (originData) === 'function') {
    callBack = originData;
    originData = undefined;
  }

  let status = this.status;
  let originTrees = originData || status.initTreeNodes;

  // 用于保存所有节点对象，以节点id作为key，以便直接查找子节点
  let treeNodeAll = {};
  Utils.asyncEach(originTrees, (dataItem) => {
    // console.log(dataItem)
    dataItem.isLeaf = true;
    dataItem.title = dataItem.displayName;
    dataItem.memberCount = dataItem.memberCount;
    dataItem.description = dataItem.description;
    dataItem.key = dataItem.id;
    treeNodeAll[dataItem.id] = dataItem;

  }, () => {
    // console.log(treeNodeAll)
    // 重组treeNode,将获取到的数据组装成tree组件需要的数据
    let nodes = Utils.renderTreeNode(treeNodeAll);
    // 保存为数组类型
    console.log(nodes)
    status.treeNodes = nodes;
    // 保存为对象类型
    status.treeNodeAll = treeNodeAll;
    // console.log('转换后的节点数据↓')
    // console.log(status.treeNodes)
    if (callBack) {
      callBack();
    }
  });
}



  /*********************************************************************************************************************
   * 保证刷新树时或者提交树结构数据时可以直接使用原始数据(可以不使用组件重新组装后的数据)
   * @param addNode 新添加的节点
   ***********************************************************************************************************************/
  public renderTreeNodes(addNode ?) {
  console.log('renderTreeNodes');
  // 原始树结构数据
  let treeNodes = this.status.treeNodes;
  // 当前添加（或修改后）子节点的节点
  let activedNode = this.status.activedNode;
  // 返回匹配到的原始数据节点
  let resultNode;
  // 深度优先遍历节点
  let eachNodes = (eachNode) => {
    let i = 0, len = eachNode.length, node;
    for (; i < len; i++) {
      node = eachNode[i];
      if (node.key === activedNode.key) {
        if (addNode) {
          // 展开(显示新增的子节点)
          node['expanded'] = true;
          node['isExpanded'] = true;
          // 因为添加了子节点，isLeaf设置为false(是否为最后一个节点：false)
          node['isLeaf'] = false;
          node.children = node.children || [];
          node.children.push(addNode);
        }
        resultNode = node;
        // 当查找到后就停止继续遍历
        break;
      }
      if (node.children) {
        // 如果有子节点，递归继续查找
        eachNodes(node.children);
      }
    }
  }
  eachNodes(treeNodes);

  return resultNode;
}

  /***************************************************************************************************************************
   * 需要刷新树形结构目录时调用该函数                                                                                            *
   * @param flag <bool> 控制是否调用                                                                                           *
   ***************************************************************************************************************************/
  public refreshTreeNode(flag, res ?) {
  let refreshTreeNodeFn = this.status.refreshTreeNodeFn.bind(this);

  if (refreshTreeNodeFn) {
    refreshTreeNodeFn(flag, res);
  }
}


// 新增部门
addDepartment() {
  this.status.ismodify = true;
}
  // 新增保存
  protected saveDepartment() {
  this.addSave()
}

// 确定添加保存
addSave() {
  if (!this.status.title) {
    this.message.warning('名称不能为空');
  }  else {
    let params = {
      parentId: this.status.activedNode ? this.status.activedNode.origin.key : null,
      displayName: this.status.title,
      // sort: this.status.editNode.origin.sort,
      // level: this.status.editNode.origin.level,
      sort: 0,
      level: 0,
      description: this.status.description
    };
    // 添加部门接口请求
    this.departmentService.CreateOrganizationUnitExtend(params).then((res) => {
      if (res.success) {
        this.message.success('添加成功');
        // console.log(res)
        // 判断是否在根目录下渲染
        let activedNode = this.status.activedNode;
        if (activedNode) {
          // 在当前选中节点下添加

          // 展开(显示新增的子节点)
          activedNode['expanded'] = true;
          activedNode['isExpanded'] = true;
          // 因为添加了子节点，isLeaf设置为false(是否为最后一个节点：false)
          activedNode['isLeaf'] = false;
          // 重置刷新树函数
          this.status.refreshTreeNodeFn = (flag, result?) => {
            if (flag) {
              // tslint:disable-next-line: max-line-length
              let nodeData = { title: res.result.displayName, description: res.result.description, memberCount: 0, key: res ? res.result.id : '', isLeaf: true };
              // 将新增项添加到原始数据中,重新渲染树时用
              // this.renderTreeNodes(nodeData);
              // 添加子节点
              activedNode.addChildren([nodeData]);
              console.log(activedNode)
            }
          };
          // 重新渲染树(调用了修改后的refreshTreeNodeFn 函数)
          this.refreshTreeNode(res.success);
        } else {
          this.init();
        }

      } else {
        this.message.warning(res.error.message);
      }
      //  结束后关闭弹出框,清空输入框值
      this.status.activedNode = null;
      this.status.ismodify = false;
      this.status.title = null;
      this.status.description = null;
    });
  }
}

// 编辑部门
editDeparment(node) {
  // console.log(node)
  // 获取当前编辑节点并保存
  this.status.editNode = node;
  this.status.isedit = true;
  // 绑定输入框的值
  this.status.title = this.status.editNode.origin.title;
  this.status.description = this.status.editNode.origin.description;
}

// 确定编辑保存
editSave() {
  if (!this.status.title) {
    this.message.warning('名称不能为空');
  }  else {
    //  保存变更后的参数
    let params = {
      id: this.status.editNode.origin.key,
      displayName: this.status.title,
      sort: this.status.editNode.origin.sort,
      level: this.status.editNode.origin.level,
      description: this.status.description
    };

    // 发起编辑部门接口请求
    this.departmentService.UpdateOrganizationUnit(params).then((res) => {
      if (res.success) {
        // res 为返回当前修改后的节点
        this.message.success('修改成功');
        let newNodeValue = res.result;

        // 重置刷新树函数
        this.status.refreshTreeNodeFn = (flag) => {
          if (flag) {
            // 改变保存的当前节点值（根据不通操作变化）
            this.status.activedNode = this.status.editNode;
            this.status.activedNode.origin.title = newNodeValue.displayName;
            this.status.activedNode.origin.description = newNodeValue.description;
            // console.log(this.status.activedNode)
            // 在原数据中找到这个修改或添加的节点并返回该节点
            // let resultNode = this.renderTreeNodes();
            // if (resultNode) {
            //   // // 修改后树节点
            //   // resultNode['title'] = newNodeValue.displayName;
            //   // resultNode['description'] = newNodeValue.description;
            //   console.log(resultNode)
            // }
          }
        };
        // 重新渲染树(调用了refreshTreeNodeFn 函数)
        this.refreshTreeNode(res.success);

      } else {
        this.message.warning(res.error.message);
      }
      //  结束后关闭弹出框,清空输入框值
      this.status.isedit = false;
      this.status.title = null;
      this.status.description = null;
    });
  }
}
// 删除
deleteDepartment(node) {
  // this.status.isDelete = true;
  // // 保存当前待编辑节点
  this.status.editNode = node
  // console.log(node)
  this.status.title = this.status.editNode.origin.title;
  this.modalService.error({
    nzTitle: `确认要删除${this.status.title}该项吗?`,
    nzContent: '<b style="color: red;">删除后不能恢复，请谨慎操作。</b>',
    nzOkText: '确定',
    nzOkType: 'danger',
    nzOnOk: () => {
      this.delNode()
    },
    nzCancelText: '取消',
    nzOnCancel: () => { }
  });
}
// 确定删除

delNode() {
  let params = {
    id: this.status.editNode.key
  }
  console.log(params)
  this.departmentService.DeleteOrganizationUnit(params).then((res) => {
    if (res.success) {
      this.message.success('删除成功');
      this.init()
    } else {
      this.message.error(Utils.errorMessageProcessor(res, Lang.deleteFail));
    }
    this.status.isDelete = false;
    this.status.editNode = null;
    this.status.activedNode = null;
    this.status.title = null;
    this.status.description = null;
  });
}
// 取消删除
Canceldel() {
  this.status.isDelete = false;
  this.status.editNode = null;
  this.status.activedNode = null;
  this.status.title = null;
  this.status.description = null;
}


// 取消编辑或添加
cancelAddOredit() {
  this.status.isDelete = false;
  this.status.editNode = null;
  this.status.isedit = false;
  this.status.ismodify = false;
  this.status.isOkLoading = false;
  this.status.title = null;
  this.status.description = null;
  // this.status.ChoosedRoleAuthority = null;
  console.log('输入数据已清除');
}

// 点击节点事件 
nzClick(event: NzFormatEmitEvent): void {
  const flag: any = event.node;
  if(!this.status.activedNode) {
  this.status.activedNode = flag;
} else if (flag !== this.status.activedNode) {
  this.status.activedNode = event.node;
} else {
  this.status.activedNode = null;
}
  }

// 修改结构树顺序弹框
async changeSort() {
  this.status.ischangeSort = true;
  await this.init()
}
// 保存节点顺序
saveSort(): void {
  console.log(this.status.dragArr);
  const params = this.status.dragArr;
  this.departmentService.BatchMoveOrganBySort(params).then((res) => {
    if (res.success) {
      this.message.success('移动成功');
      this.init()
      this.handleCancel();
    } else {
      this.message.error(Utils.errorMessageProcessor(res, Lang.deleteFail));
      this.handleCancel();
    }

  });
}
// 取消修改
handleCancel(): void {
  this.status.dragArr = [];
  this.status.ischangeSort = false;
}

// 拖拽事件

// 拖拽结束前
beforeDrop(arg: NzFormatBeforeDropEvent): Observable < boolean > {
  console.log(arg)
    return of(true)
}

//  拖动事件
nzEvent(event: NzFormatEmitEvent): void {
  // console.log(event);

  if(event.eventName == 'dragend') {
  console.log(event);
  // 当前拖动元素的level
  this.status.dragNodelevel = event.dragNode.level;
  // 当前拖动元素的ID 
  this.status.dragNodeId = event.dragNode.origin.key;
  // 当前拖动结束后目标位置的parentID
  let parentKey = event.dragNode.parentNode ? event.dragNode.parentNode.origin.key : 0;
  this.status.dragNodePid = parentKey;
  // 获取当前元素的前一个元素
  this.status.dragBeforeNodeid = event.node.key;

  // 如果不是平级拖动
  if (event.dragNode.parentNode) {
    let newArr = event.dragNode.parentNode.children;
    newArr.forEach((a) => {
      // console.log(a.title)
      this.status.dragNodeTitle = event.dragNode.title;

    })
    // 获取当前拖动元素的sort
    // console.log(newArr.findIndex((element) => (element.title == this.status.dragNodeTitle)));
    this.status.dragNodeSort = newArr.findIndex((element) => (element.title == this.status.dragNodeTitle)) + 1;
  } else {
    //  根目录拖动时
    console.log(this.status.treeNodes)
    console.log(this.status.dragNodeId)
    this.status.dragNodeSort = this.status.treeNodes.findIndex((element) => (element.id == this.status.dragBeforeNodeid)) + 1;
  }
  let params = {
    TargetOrganId: this.status.dragNodeId,
    TargetParentId: this.status.dragNodePid,
    level: this.status.dragNodelevel,
    sort: this.status.dragNodeSort,
    TargetBeforeId: this.status.dragBeforeNodeid
  }
  console.log(params)
  // if (params.newParentId) {
  this.status.dragArr.push(params);
  // }

}


  }


  /**
   * 关键字搜索
   */
  public searchEvent() {
  this.init();
}
  /**
   * 搜索框回车事件
   * @param e <Event>
   */
  public keyupEvent(e: Event) {
  Utils.enter(e, this.searchEvent.bind(this));
}


constructor(private departmentService: DepartmentService,
  public message: NzMessageService,
  private modalService: NzModalService) { }

ngOnInit() {

  this.init()
}

}
